package wordit.impl.letterCells;

import java.util.Vector;
import wordit.Game;
import wordit.ea.CrossoverFunction;
import wordit.ea.Genome;

public class LetterCellCrossover implements CrossoverFunction {

	private int numOfRowsOnBoard;
	private int numOfColumnsOnBoard;
	
	public LetterCellCrossover (Game game) {
		numOfRowsOnBoard = game.getNumOfRows();
		numOfColumnsOnBoard = game.getNumOfColumns();
	}
	
	@Override
	public Genome[] crossGenoms(Genome parent1, Genome parent2) {
		
		Genome[] offsprings = new Genome[2];
		LetterCellGenome LCGenome1 = (LetterCellGenome) parent1;
		LetterCellGenome LCGenome2 = (LetterCellGenome) parent2;
		int numOfLetterCells = LCGenome1.getNumOfLetterCells();
		
		LetterCellGenome offspring1 = new LetterCellGenome(numOfRowsOnBoard, numOfColumnsOnBoard);
		LetterCellGenome offspring2 = new LetterCellGenome(numOfRowsOnBoard, numOfColumnsOnBoard);
		
		for (int i=0; i<(numOfLetterCells/2); i++) {
			offspring1.addLetterCell(LCGenome1.getLetterCellAt(i));
			offspring2.addLetterCell(LCGenome2.getLetterCellAt(i));
		}
		
		for (int i=(numOfLetterCells/2); i<numOfLetterCells; i++) {
			offspring1.addLetterCell(LCGenome2.getLetterCellAt(i));
			offspring2.addLetterCell(LCGenome1.getLetterCellAt(i));
		}		

		offsprings[0] = fixOffspring (offspring1);
		offsprings[1] = fixOffspring (offspring2);
		
		//TODO: Remove Prints:
		/*
		System.out.println("Parents:");
		System.out.println("Parrent 1: " + parent1.toString());		
		System.out.println("Parrent 2: " + parent2.toString());	
		System.out.println("Before Fix:");
		System.out.println("Offspring 1: " + offspring1.toString());
		System.out.println("Offspring 2: " + offspring2.toString());
		System.out.println("After Fix:");
		System.out.println("Offspring 1: " + offsprings[0].toString());
		System.out.println("Offspring 2: " + offsprings[1].toString());
		*/
		
		return offsprings;
	}
	
	private LetterCellGenome fixOffspring (LetterCellGenome offspring) {
		
		//list of pairs, such that each pair is the INDEXES of two conflicting Letter Cells 
		//in the genome (two different letters placed on the same cell of the board)
		Vector<int[]> conflictingLetterCells = new Vector<int[]>(); 
		
		//Collects to the list all of the conflicting indexes
		for (int i=0; i<offspring.getNumOfLetterCells(); i++) {
			for (int j=i+1; j<offspring.getNumOfLetterCells(); j++) {
				if (offspring.getLetterCellAt(i).getCell() ==
					offspring.getLetterCellAt(j).getCell()) {
					int[] pair = new int[2];
					pair[0] = i;
					pair[1] = j;
					conflictingLetterCells.add(pair);
				}
			}
		}
		
		//Randomly chooses which letter stays on its place 
		//and which moved and moves all the letters selected
		for (int i=0; i<conflictingLetterCells.size(); i++) {
			int vacantLocation;
			
			do {
				vacantLocation = (int) (Math.random() * numOfRowsOnBoard * numOfColumnsOnBoard);
			} while (offspring.getLetterAt(vacantLocation)!=null);
			
			int conflictingCellIndex;
			
			if (Math.random() < 0.5) {
				conflictingCellIndex = conflictingLetterCells.get(i)[0];
			} else {
				conflictingCellIndex = conflictingLetterCells.get(i)[1];	
			}
			offspring.setLetterCellAt(conflictingCellIndex,
					new LetterCell (offspring.getLetterCellAt(conflictingCellIndex).getLetter(), 
									vacantLocation));
		}
					
		return offspring;
	}

}
